package cn.changeforyou.web.dao.mybatis.ext.extBuilder.builder;

import cn.changeforyou.web.dao.mybatis.ext.extBuilder.DaoSpringHolder;
import cn.changeforyou.web.dao.mybatis.ext.extBuilder.SqlContext;
import cn.changeforyou.web.dao.mybatis.ext.extBuilder.TableInfoForm;
import cn.changeforyou.web.dao.mybatis.ext.extBuilder.writer.*;
import cn.changeforyou.web.dao.mybatis.ext.metaInfo.EntityMetaInfo;
import cn.changeforyou.web.dao.mybatis.ext.metaInfo.FieldMetaInfo;
import cn.changeforyou.web.dao.mybatis.ext.metaInfo.MappedStatementMetaInfo;
import cn.changeforyou.web.dao.mybatis.ext.metaInfo.MappedStatementParameterType;

import java.util.ArrayList;
import java.util.List;

/**
 * delete语句构建器
 * @author zhyu
 * @version 1.0
 * @date 2022/2/10 16:36
 */
public class DeleteBuilder {

    private static FromSimpleSqlWriter fromSimpleSqlWriter;
    private static WhereEmptyAndIdSqlWriter whereEmptyAndIdSqlWriter;
    private static WhereConditionSqlWriter whereConditionSqlWriter;
    static {
        fromSimpleSqlWriter = DaoSpringHolder.getBean(FromSimpleSqlWriter.class);
        whereEmptyAndIdSqlWriter = DaoSpringHolder.getBean(WhereEmptyAndIdSqlWriter.class);
        whereConditionSqlWriter = DaoSpringHolder.getBean(WhereConditionSqlWriter.class);
    }

    /**
     * 构建
     *
     * @param mappedStatementMetaInfo
     * @return
     */
    public static void buildAndSet(MappedStatementMetaInfo mappedStatementMetaInfo) {
        SqlContext sqlContext = prepareBuild(mappedStatementMetaInfo);

        //delete语句
        SqlBuilder sqlBuilder = sqlContext.getSql();
        sqlBuilder.append(" DELETE");

        //from 语句
        fromSimpleSqlWriter.writeSql(sqlContext);

        //where语句
        switch (sqlContext.getMappedStatementParameterType()) {
            case deleteByEntity:
                whereConditionSqlWriter.writeSql(sqlContext);
                break;
            case deleteById:
                whereEmptyAndIdSqlWriter.writeSql(sqlContext);
                break;
        }

        String sql = afterBuilder(sqlContext);
        mappedStatementMetaInfo.setSql(sql);
    }

    private static SqlContext prepareBuild(MappedStatementMetaInfo mappedStatementMetaInfo) {
        SqlContext sqlContext = new SqlContext();
        EntityMetaInfo entityMetaInfo = mappedStatementMetaInfo.getEntityMetaInfo();
        sqlContext.setSqlCommandType(mappedStatementMetaInfo.getSqlCommandType());
        sqlContext.setScriptModel(true);
        sqlContext.setMappedStatementResultType(mappedStatementMetaInfo.getMappedStatementBaseInfo().getMappedStatementResultType());
        MappedStatementParameterType mappedStatementParameterType = mappedStatementMetaInfo.getMappedStatementBaseInfo().getMappedStatementParameterType();
        sqlContext.setMappedStatementParameterType(mappedStatementParameterType);

        TableInfoForm tableInfoForm = new TableInfoForm();
        tableInfoForm.setTableName(entityMetaInfo.getTableName());
        tableInfoForm.setTableAlias(entityMetaInfo.getTableNameAlias());
        sqlContext.setMainTableForm(tableInfoForm);

        for (FieldMetaInfo fieldMetaInfo : entityMetaInfo.getFieldMetaInfoList()) {
            if (fieldMetaInfo.isId()) {
                sqlContext.setPrimaryKeyInfo(fieldMetaInfo);
                break;
            }
        }
        switch (mappedStatementParameterType) {
            case deleteByEntity:
                List<FieldMetaInfo> primaryKeyField = new ArrayList<>();
                primaryKeyField.add(sqlContext.getPrimaryKeyInfo());
                WhereBuildUtil.buildWhereTreeByFieldMetaInfoList(primaryKeyField, sqlContext);
                break;
        }
        return sqlContext;
    }

    /**
     * build后方法
     *
     * @param context
     * @return
     */
    private static String afterBuilder(SqlContext context) {
        if (context.isScriptModel()) {
            return "<script>" + context.getSql().toString() + "</script>";
        }
        return context.getSql().toString();
    }
}
